import { logger } from '../types/constants'

// 类型定义
interface UserAgentData {
  brands?: Array<{
    brand: string
    version: string
  }>
  mobile?: boolean
  platform?: string
  architecture?: string
  bitness?: string
}

export interface SystemInfoData {
  browser: BrowserInfo
  os: string
  isIncognito?: string
  architecture?: string
  userAgent?: string
}

export interface BrowserInfo {
  name: string
  version: string
  fullName: string
  handler: string
  handlerVersion: string
  handlerFullName: string
}

/**
 * 系统信息检测模块
 * 优先使用 GM_info.userAgentData 获取系统信息，回退到 navigator.userAgent
 */
export class SystemInfo {
  private readonly GM_INFO
  private readonly UNKNOWN_VALUE: string

  constructor() {
    this.GM_INFO = GM_info || {}
    this.UNKNOWN_VALUE = '未知'
  }

  /**
   * 获取完整的系统信息
   * @returns 包含浏览器、操作系统和用户代理的系统信息对象
   */
  public getSystemInfo(): SystemInfoData {
    try {
      const uaData: UserAgentData = 'userAgentData' in this.GM_INFO ? this.GM_INFO.userAgentData as UserAgentData : {}

      // 优先使用 GM_info.userAgentData 获取信息
      const result: SystemInfoData = {
        browser: this.getBrowserInfo(uaData),
        os: this.getOSInfo(uaData),
        isIncognito: typeof this.GM_INFO.isIncognito === 'boolean'
          ? (this.GM_INFO.isIncognito ? '是' : '否')
          : this.UNKNOWN_VALUE,
        architecture: `${uaData.architecture}_${uaData.bitness}` || this.UNKNOWN_VALUE,
        userAgent: navigator.userAgent || this.UNKNOWN_VALUE,
      }

      // 如果通过 GM_info 获取的信息不完整，回退到 navigator.userAgent
      if (result.browser.name === this.UNKNOWN_VALUE || result.os === this.UNKNOWN_VALUE) {
        const fallbackInfo = this.getFallbackSystemInfo()
        if (result.browser.name === this.UNKNOWN_VALUE) {
          result.browser = fallbackInfo.browser
        }
        if (result.os === this.UNKNOWN_VALUE) {
          result.os = fallbackInfo.os
        }
      }

      return result
    }
    catch (error: any) {
      logger.error('获取系统信息失败，使用回退方案', error)
      return this.getFallbackSystemInfo()
    }
  }

  /**
   * 从 GM_info.userAgentData 获取浏览器信息
   * @param uaData GM_info.userAgentData 对象
   * @returns 浏览器信息对象
   */
  private getBrowserInfo(uaData: UserAgentData): BrowserInfo {
    // 优先从 brands 数组中获取浏览器信息
    if (uaData.brands?.length) {
      const browsers = ['Firefox', 'Edge', 'Chrome', 'Safari']
      for (const browser of browsers) {
        const browserBrand = uaData.brands.find(b => b.brand.includes(browser))
        if (browserBrand) {
          return {
            name: browserBrand.brand,
            version: browserBrand.version,
            fullName: `${browserBrand.brand} ${browserBrand.version}`,
            handler: this.GM_INFO.scriptHandler || this.UNKNOWN_VALUE,
            handlerVersion: (this.GM_INFO?.version) || this.UNKNOWN_VALUE,
            handlerFullName: `${this.GM_INFO.scriptHandler || this.UNKNOWN_VALUE} ${this.GM_INFO?.version || this.UNKNOWN_VALUE}`,
          }
        }
      }
    }

    // 回退到 navigator.userAgent 检测
    return this.detectBrowserFromUserAgent()
  }

  /**
   * 从 GM_info.userAgentData 获取操作系统信息
   * @param uaData GM_info.userAgentData 对象
   * @returns 操作系统名称
   */
  private getOSInfo(uaData: any): string {
    if (uaData.platform) {
      return this.normalizeOSName(uaData.platform)
    }
    return this.detectOSFromUserAgent()
  }

  /**
   * 通过 navigator.userAgent 获取系统信息（回退方案或降级方案）
   * @returns 系统信息对象
   */
  private getFallbackSystemInfo(): SystemInfoData {
    return {
      browser: this.detectBrowserFromUserAgent(),
      os: this.detectOSFromUserAgent(),
    }
  }

  /**
   * 从 userAgent 字符串检测浏览器信息
   * @returns 浏览器信息对象
   */
  private detectBrowserFromUserAgent(): BrowserInfo {
    const ua = navigator.userAgent || ''
    let name = this.UNKNOWN_VALUE
    let version = this.UNKNOWN_VALUE

    // 浏览器检测逻辑
    const browsers = [
      { name: 'Firefox', regex: /Firefox\/(\d+\.\d+)/ },
      { name: 'Edge', regex: /Edg\/(\d+\.\d+)/ },
      { name: 'Chrome', regex: /Chrome\/(\d+\.\d+)/ },
      { name: 'Safari', regex: /Version\/(\d+\.\d+)/ },
    ]

    for (const browser of browsers) {
      const match = ua.match(browser.regex)
      if (match) {
        name = browser.name
        version = match[1]
        break
      }
    }

    return {
      name,
      version,
      fullName: `${name} ${version}`,
      handler: this.GM_INFO.scriptHandler || this.UNKNOWN_VALUE,
      handlerVersion: (this.GM_INFO?.version) || this.UNKNOWN_VALUE,
      handlerFullName: `${this.GM_INFO.scriptHandler || this.UNKNOWN_VALUE} ${this.GM_INFO?.version || this.UNKNOWN_VALUE}`,
    }
  }

  /**
   * 从 userAgent 字符串检测操作系统
   * @returns 操作系统名称
   */
  private detectOSFromUserAgent(): string {
    const ua = navigator.userAgent || ''
    const osMap = [
      { name: 'Windows', test: /Windows/ },
      { name: 'Mac OS', test: /Mac/ },
      { name: 'Linux', test: /Linux/ },
      { name: 'Android', test: /Android/ },
      { name: 'iOS', test: /(iPhone|iPad|iPod)/ },
    ]

    for (const os of osMap) {
      if (os.test.test(ua)) {
        return os.name
      }
    }

    return this.UNKNOWN_VALUE
  }

  /**
   * 标准化操作系统名称
   * @param osName 原始操作系统名称
   * @returns 标准化后的名称
   */
  private normalizeOSName(osName: string): string {
    const mapping: Record<string, string> = {
      'Win': 'Windows',
      'MacIntel': 'Mac OS',
      'Linux x86_64': 'Linux',
      'Android': 'Android',
      'iPhone': 'iOS',
    }

    return mapping[osName] || osName
  }
}
